using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using LinkNote.Model;

namespace LinkNote
{
    public class CommonAdapter<T> : BaseAdapter where T : BaseModel {
	
	    protected Context	mContext;
        protected List<T> data;
        protected LayoutInflater mInflater;
        protected int layout;
        protected string[] cols;
        protected int[] ids;
	
	    private CommonAdapter(Context c, List<T> data, int cellViewLayout, string[] columns, int[] viewIDs){
		    mContext = c;
		    this.data = data;
		    this.mInflater = LayoutInflater.From(mContext);
            cols = columns;
            ids = viewIDs;
            layout = cellViewLayout;

            //ShowItemEvent = showItem;
	    }

        public CommonAdapter(Context c, List<T> data, int cellViewLayout)
            :this(c, data, cellViewLayout, null, null)
        {
        }
	
	    public override int Count {
            get
            {
                return data.Count;
            }
	    }

	    public override Java.Lang.Object GetItem(int position) {
		    return data[position];
	    }

	    public override long GetItemId(int position) {
		    return position;
	    }

	    public override View GetView(int position, View convertView, ViewGroup parent) {

            //ViewHolder holder;
            if (convertView == null)
            {
                convertView = mInflater.Inflate(layout, parent, false);
                convertView.Click += OnItemClick;

                //holder = new ViewHolder();
                //int count = Math.Min(cols.Length, ids.Length);
                //for (int i = 0; i < count; i++)
                //{
                //    View v = convertView.FindViewById(ids[i]);
                //    holder.views.Add(ids[i], v);
                //}
                //convertView.Tag = holder;
            }
            //else
            //{
            //    holder = (ViewHolder)convertView.Tag;
            //}

            T item = data[position];
            convertView.Tag = item;
            //showItem(item, convertView);
            if (ShowItemEvent != null)
                ShowItemEvent(item, convertView);
            return convertView;
	    }

        //private void showItem(T item, View convertView)
        //{
        //    if (cols == null || ids == null) return;

        //    int count = Math.Min(cols.Length, ids.Length);
        //    for (int i = 0; i < count; i++)
        //    {
        //        View v = convertView.FindViewById(ids[i]);
        //        switch (v.GetType().Name)
        //        {
        //            case "TextView":
        //                (v as TextView).Text = item[cols[i]].ToString();
        //                break;
        //            case "EditText":
        //                (v as EditText).Text = item[cols[i]].ToString();
        //                break;
        //        }
        //    }
        //}

        protected event ShowItemDelegate<T> ShowItemEvent;
        public void SetShowItemDelegate(ShowItemDelegate<T> dele)
        {
            ShowItemEvent = dele;
        }

        private void OnItemClick(object s, EventArgs v)
        {
            if (ItemClick != null)
            {
                View sender = s as View;
                T nc = sender.Tag as T;
                ItemClick(sender, nc);
            }
        }

        public event ItemClickDelegate<T> ItemClick;
	
        //public class ViewHolder : Java.Lang.Object {
        //    public Dictionary<int, View> views = new Dictionary<int, View>();
        //}

    }

    public delegate void ShowItemDelegate<T>(T item, View convertView);
    public delegate void ItemClickDelegate<T>(View convertView, T item);
    public delegate void ShowGroupItemDelegate<T>(T item, View convertView, bool isExpand);

    public class CommonExpandableAdapter<T> : BaseExpandableListAdapter
        where T : BaseModel, ITree<T>
    {
        protected Context mContext;
        protected List<T> data;
        protected LayoutInflater mInflater;
        protected int parentViewLayout;
        protected int childViewLayout;
        protected ExpandableListView listview;

        public CommonExpandableAdapter(Context c, ExpandableListView listview, List<T> data, int parentViewLayout, int childViewLayout)
        {
            mContext = c;
            this.listview = listview;
            this.data = data;
            this.mInflater = LayoutInflater.From(mContext);
            this.parentViewLayout = parentViewLayout;
            this.childViewLayout = childViewLayout;
        }

        public override Java.Lang.Object GetChild(int groupPosition, int childPosition)
        {
            T item = data[groupPosition];
            return item.Childs[childPosition];
        }

        public override long GetChildId(int groupPosition, int childPosition)
        {
            T item = data[groupPosition];
            return item.Childs[childPosition].ID;
        }

        public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
        {
            if (convertView == null)
            {
                convertView = mInflater.Inflate(childViewLayout, parent, false);
                convertView.Click += OnChildItemClick;
            }

            T item = data[groupPosition];
            T childitem = item.Childs[childPosition];
            convertView.Tag = childitem;
            if (ShowChildItemEvent != null)
                ShowChildItemEvent(childitem, convertView);
            return convertView;
        }

        public override int GetChildrenCount(int groupPosition)
        {
            T item = data[groupPosition];
            return item.ChildCount;
        }

        public override Java.Lang.Object GetGroup(int groupPosition)
        {
            return data[groupPosition];
        }

        public override long GetGroupId(int groupPosition)
        {
            return data[groupPosition].ID;
        }

        public override View GetGroupView(int groupPosition, bool isExpanded, View convertView, ViewGroup parent)
        {
            if (convertView == null)
            {
                convertView = mInflater.Inflate(parentViewLayout, parent, false);
                convertView.Click += OnGroupItemClick;
                convertView.Click += delegate
                {
                    if (listview.IsGroupExpanded(groupPosition))
                        listview.CollapseGroup(groupPosition);
                    else
                        listview.ExpandGroup(groupPosition);
                };
            }

            T item = data[groupPosition];
            convertView.Tag = item;
            if (ShowGroupItemEvent != null)
                ShowGroupItemEvent(item, convertView, isExpanded);
            return convertView;
        }

        public override int GroupCount
        {
            get { return data.Count; }
        }

        public override bool HasStableIds
        {
            get { return true; }
        }

        public override bool IsChildSelectable(int groupPosition, int childPosition)
        {
            return true;
        }

        protected event ShowGroupItemDelegate<T> ShowGroupItemEvent;
        public void SetShowGroupItemDelegate(ShowGroupItemDelegate<T> dele)
        {
            ShowGroupItemEvent = dele;
        }

        protected event ShowItemDelegate<T> ShowChildItemEvent;
        public void SetShowChildItemDelegate(ShowItemDelegate<T> dele)
        {
            ShowChildItemEvent = dele;
        }

        private void OnGroupItemClick(object s, EventArgs v)
        {
            if (GroupItemClick != null)
            {
                View sender = s as View;
                T nc = sender.Tag as T;
                GroupItemClick(sender, nc);
            }
        }
        public event ItemClickDelegate<T> GroupItemClick;

        private void OnChildItemClick(object s, EventArgs v)
        {
            if (ChildItemClick != null)
            {
                View sender = s as View;
                T nc = sender.Tag as T;
                ChildItemClick(sender, nc);
            }
        }
        public event ItemClickDelegate<T> ChildItemClick;
    }
}